// Copyright (c) Microsoft
// All rights reserved
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
// INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
// See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
/// <tags>P1</tags>
/// <summary>Test pad() function on tiled_extent.</summary>
// RUN: %amp_device -D__GPU__ %s -m32 -emit-llvm -c -S -O3 -o %t.ll && mkdir -p %t
// RUN: %llc -march=c -o %t/kernel_.cl < %t.ll
// RUN: cat %opencl_math_dir/opencl_math.cl %t/kernel_.cl > %t/kernel.cl
// RUN: pushd %t && objcopy -B i386:x86-64 -I binary -O elf64-x86-64 kernel.cl %t/kernel.o && popd
// RUN: %cxxamp %link %t/kernel.o %s -o %t.out && %t.out
#include <amp.h>
using namespace concurrency;
#define INVOKE_TEST_FUNC_ON_CPU_AND_GPU(_func, ...) [&]() { \
	/* Invoke on cpu */ \
	int cpu_result = _func(__VA_ARGS__); \
	/* Invoke on gpu */ \
	int gpu_result; \
	concurrency::array_view<int, 1> gpu_resultv(1, &gpu_result); \
    gpu_resultv.discard_data(); \
	concurrency::parallel_for_each(gpu_resultv.get_extent() \
		, [=](concurrency::index<1> idx) restrict(amp) { \
		gpu_resultv[idx] = _func(__VA_ARGS__); \
	}); \
	gpu_resultv.synchronize(); \
		return cpu_result & gpu_result; \
}()
bool test() restrict(cpu,amp)
{
	extent<1> g1(25);
	auto tg1 = g1.tile<4>();
	auto ptg1 = tg1.pad();
	if (ptg1[0] != 28)
		return false;

	extent<2> g2(25,51);
	auto tg2 = g2.tile<4,8>();
	auto ptg2 = tg2.pad();
	if (ptg2[0] != 28)
		return false;
	if (ptg2[1] != 56)
		return false;

	extent<3> g3(25,51,85);
	auto tg3 = g3.tile<4,8,16>();
	auto ptg3 = tg3.pad();
	if (ptg3[0] != 28)
		return false;
	if (ptg3[1] != 56)
		return false;
	if (ptg3[2] != 96)
		return false;

	return true;
}

int main()
{
	//accelerator_view av = require_device().get_default_view();

	int result = 1;
	result &= INVOKE_TEST_FUNC_ON_CPU_AND_GPU(test);
	return result;
}
